home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / PPPPAP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-28  |  16.1 KB  |  683 lines

  1. /*
  2.  *  PPPPAP.C    -- Password Authentication Protocol for PPP
  3.  *
  4.  *    This implementation of PPP is declared to be in the public domain.
  5.  *
  6.  *    Jan 91    Bill_Simpson@um.cc.umich.edu
  7.  *        Computer Systems Consulting Services
  8.  *
  9.  *    Acknowledgements and correction history may be found in PPP.C
  10.  *
  11.  * Mods by PA0GRI
  12.  */
  13. #include "global.h"
  14. #include "mbuf.h"
  15. #include "proc.h"
  16. #include "iface.h"
  17. #include "session.h"
  18. #include "ppp.h"
  19. #include "pppfsm.h"
  20. #include "ppplcp.h"
  21. #include "ppppap.h"
  22. #include "cmdparse.h"
  23. #include "files.h"
  24. #include "trace.h"
  25. #include "main.h"
  26.  
  27. #if !defined(_lint)
  28. static char rcsid[] OPTIONAL = "$Id: ppppap.c,v 1.16 1996/12/29 02:47:22 root Exp root $";
  29. #endif
  30.  
  31. #ifdef PPP
  32.  
  33. static int dopap_user (int argc, char *argv[], void *p);
  34. static void pap_monitor (int mustask, void *v1, void *v2);
  35. static void pap_pwdlookup (struct pap_s * pap_p);
  36. static struct mbuf *pap_makereq (struct fsm_s * fsm_p);
  37. static int pap_verify (char *username, char *password);
  38. static void pap_shutdown (struct fsm_s * fsm_p);
  39. static void pap_opening (struct fsm_s * fsm_p, int flag);
  40. static int pap_request (struct fsm_s * fsm_p, struct config_hdr * hdr, struct mbuf * data);
  41. static int pap_check (struct fsm_s * fsm_p, struct config_hdr * hdr, struct mbuf * data);
  42. static void pap_timeout (void *vp);
  43. static void pap_free (struct fsm_s * fsm_p);
  44.  
  45.  
  46. static struct fsm_constant_s pap_constants =
  47. {
  48.     "Pap",
  49.     PPP_PAP_PROTOCOL,
  50.     0x000E,            /* codes 1-3 recognized */
  51.  
  52.     Pap,
  53.     PAP_REQ_TRY,
  54.     PAP_FAIL_MAX,
  55.     0,
  56.     PAP_TIMEOUT * 1000L,
  57.  
  58.     pap_free,
  59.  
  60.     fsm_no_action,        /* pap_reset, */
  61.     fsm_no_action,        /* pap_starting, */
  62.     fsm_no_action,        /* pap_opening, */
  63.     fsm_no_action,        /* pap_closing, */
  64.     fsm_no_action,        /* pap_stopping, */
  65.  
  66.     pap_makereq,
  67.     fsm_no_check,        /* pap_request, */
  68.     fsm_no_check,        /* pap_ack, */
  69.     fsm_no_check,        /* pap_nak, */
  70.     fsm_no_check,        /* pap_reject */
  71. };
  72.  
  73.  
  74.  
  75. /****************************************************************************/
  76.  
  77. /* "ppp <iface> pap" subcommands */
  78. static struct cmds Papcmds[] =
  79. {
  80.     { "timeout",    doppp_timeout,    0, 0, NULLCHAR },
  81.     { "try",    doppp_try,    0, 0, NULLCHAR },
  82.     { "user",    dopap_user,    0, 0, NULLCHAR },
  83.     { NULLCHAR,    NULL,        0, 0, NULLCHAR }
  84. };
  85.  
  86.  
  87.  
  88. int
  89. doppp_pap (int argc, char *argv[], void *p)
  90. {
  91. register struct iface *ifp = p;
  92. register struct ppp_s *ppp_p = ifp->edv;
  93.  
  94.     return subcmd (Papcmds, argc, argv, &(ppp_p->fsm[Pap]));
  95. }
  96.  
  97.  
  98.  
  99. /* Set user/password */
  100. int
  101. dopap_user (int argc, char *argv[], void *p)
  102. {
  103. register struct fsm_s *fsm_p = p;
  104. register struct pap_s *pap_p = fsm_p->pdv;
  105.  
  106.     if (argc < 2) {
  107.         tprintf ("%s\n", (pap_p->username == NULLCHAR) ? "None" : pap_p->username);
  108.         return 0;
  109.     }
  110.     free (pap_p->username);
  111.     pap_p->username = NULLCHAR;
  112.     free (pap_p->password);
  113.     pap_p->password = NULLCHAR;
  114.  
  115.     if (stricmp (argv[1], "none") != 0) {
  116.         pap_p->username = strdup (argv[1]);
  117.         if (argc > 2)
  118.             pap_p->password = strdup (argv[2]);
  119.         else
  120.             pap_pwdlookup (pap_p);
  121.     }
  122.     return 0;
  123. }
  124.  
  125.  
  126.  
  127. /****************************************************************************/
  128. /* Bring up a session on the console for for the username/password.
  129.  * Return a NULLCHAR in either username or password if aborted.
  130.  */
  131. static void
  132. pap_monitor (int unused OPTIONAL, void *v1, void *v2)
  133. {
  134. struct iface *iface = v1;
  135. struct fsm_s *fsm_p = v2;
  136. struct pap_s *pap_p = fsm_p->pdv;
  137. char buf[21];
  138. struct session *sp;
  139. int wait_code = 0;
  140.  
  141.     /* Allocate a session control block */
  142.     if ((sp = newsession ("PPP/PAP", PPPPASS, 0)) == NULLSESSION) {
  143.         tputs (TooManySessions);
  144.         return;
  145.     }
  146.     while (!main_exit && wait_code == 0) {
  147.         /* get user name */
  148.         if (pap_p->username == NULLCHAR) {
  149.             tprintf ("%s: PPP/PAP  Username: ", iface->name);
  150.             usflush (sp->output);
  151.             if (recvline (sp->input, (unsigned char *) buf, 20) > 0) {
  152.                 rip (buf);
  153.                 if (strlen (buf) > 0)
  154.                     pap_p->username = strdup (buf);
  155.             }
  156.         } else {
  157.             tprintf ("%s: PPP/PAP  Username: %s\n", iface->name, pap_p->username);
  158.             usflush (sp->output);
  159.         }
  160.  
  161.         /* get pass word */
  162.         if (pap_p->username != NULLCHAR && pap_p->password == NULLCHAR) {
  163.             /* turn off echo */
  164.             sp->ttystate.echo = 0;
  165.             tprintf ("%s: PPP/PAP  Password: ", iface->name);
  166.             usflush (sp->output);
  167.             if (recvline (sp->input, (unsigned char *) buf, 20) > 0) {
  168.                 rip (buf);
  169.                 if (strlen (buf) > 0)
  170.                     pap_p->password = strdup (buf);
  171.             }
  172.             tputc ('\n');
  173.             usflush (sp->output);
  174.             /* Turn echo back on */
  175.             sp->ttystate.echo = 1;
  176.         }
  177.         /* send pap request */
  178.         (void) fsm_sendreq (fsm_p);
  179.         wait_code = kwait (pap_p);
  180.  
  181.         /* show ack/nak reply */
  182.         if (wait_code != EABORT && pap_p->message != NULLCHAR)
  183.             tprintf ("%s: PPP/PAP  %s\n", iface->name, pap_p->message);
  184.  
  185.         tputc ('\n');
  186.         usflush (sp->output);
  187.  
  188.     }
  189.  
  190.     /* clean up */
  191.     if (wait_code != EABORT)
  192.         (void) kpause (10000L);
  193.  
  194.     freesession (sp);
  195.     pap_p->pp = NULLPROC;
  196. }
  197.  
  198.  
  199.  
  200. /* Check the FTP userfile for this user; get password if available */
  201. static void
  202. pap_pwdlookup (struct pap_s *pap_p)
  203. {
  204. char *buf;
  205. char *password;
  206. long permission;
  207.  
  208.     if (pap_p->username == NULLCHAR)
  209.         return;
  210.  
  211.     if ((buf = userlookup (pap_p->username, &password, NULLCHARP, &permission, NULL)) == NULLCHAR)
  212.         return;
  213.  
  214.     /* Check permissions for this user */
  215.     if ((permission & PPP_PWD_LOOKUP) == 0) {
  216.         /* Not in ftpuser file for password lookup */
  217.         free (buf);
  218.         return;
  219.     }
  220.     /* Save the password from this userfile record */
  221.     if (strlen (password) != 0)
  222.         pap_p->password = strdup (password);
  223.     free (buf);
  224. }
  225.  
  226.  
  227.  
  228. /*******************************************/
  229. /* Verify user and password sent by remote host */
  230. static int
  231. pap_verify (char *username, char *password)
  232. {
  233. int privs;
  234. char *path;
  235. int anony = 0;
  236.  
  237.     /* Use same login as FTP server */
  238.     path = mallocw (128);
  239.     privs = userlogin (username, password, &path, 128, &anony);
  240.     free (path);
  241.  
  242.     /* Check privs for this user */
  243.     if (privs == -1) {
  244.         trace_log (PPPiface, "PAP: username/password incorrect or not found: %s", username);
  245.         return -1;
  246.     }
  247.     if ((privs & PPP_ACCESS_PRIV) == 0) {
  248.         trace_log (PPPiface, "PAP: no permission for PPP access: %s", username);
  249.         return -1;
  250.     }
  251.     return 0;
  252. }
  253.  
  254.  
  255.  
  256. /****************************************************************************/
  257. /* Build a request to send to remote host */
  258. static struct mbuf *
  259. pap_makereq (struct fsm_s *fsm_p)
  260. {
  261. struct pap_s *pap_p = fsm_p->pdv;
  262. struct mbuf *req_bp = NULLBUF;
  263. register char *cp;
  264. int len;
  265.  
  266.     PPP_DEBUG_ROUTINES ("pap_makereq()");
  267.  
  268.     if (pap_p->username == NULLCHAR || pap_p->password == NULLCHAR) {
  269.         fsm_log (fsm_p, "NULL username or password");
  270.         return NULLBUF;
  271.     }
  272. #ifdef PPP_DEBUG_OPTIONS
  273.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  274.         trace_log (PPPiface, "    making user id %s", pap_p->username);
  275. #endif
  276.  
  277.     /* Get buffer for authenticate request packet */
  278.     len = (int) (2 + strlen (pap_p->username) + strlen (pap_p->password));
  279.     if ((req_bp = alloc_mbuf ((int16) len)) == NULLBUF)
  280.         return NULLBUF;
  281.  
  282.     /* Load user id and password for authenticate packet */
  283.     cp = (char *) req_bp->data;
  284.     *cp++ = (char) strlen (pap_p->username);
  285.     if (strlen (pap_p->username) > 0)
  286.         cp = stpcpy (cp, pap_p->username);
  287.  
  288.     *cp++ = (char) strlen (pap_p->password);
  289.     if (strlen (pap_p->password) > 0)
  290.         cp = stpcpy (cp, pap_p->password);
  291.  
  292.     req_bp->cnt += (int16) len;
  293.     return (req_bp);
  294. }
  295.  
  296.  
  297.  
  298. /****************************************************************************/
  299.  
  300. /* abandon PAP attempt; shutdown LCP layer */
  301. static void
  302. pap_shutdown (struct fsm_s *fsm_p)
  303. {
  304. struct ppp_s *ppp_p = fsm_p->ppp_p;
  305.  
  306.     PPP_DEBUG_ROUTINES ("pap_shutdown()");
  307.  
  308.     if (PPPtrace > 1)
  309.         fsm_log (fsm_p, "Failed; close connection");
  310.  
  311.     fsm_close (&(ppp_p->fsm[Lcp]));
  312. }
  313.  
  314.  
  315.  
  316. /* Configuration negotiation complete */
  317. static void
  318. pap_opening (struct fsm_s *fsm_p, int flag)
  319. {
  320. register struct ppp_s *ppp_p = fsm_p->ppp_p;
  321.  
  322.     fsm_log (fsm_p, "Open");
  323.  
  324.     stop_timer (&(fsm_p->timer));
  325.  
  326.     if (!((fsm_p->flags &= ~flag) & (PPP_AP_LOCAL | PPP_AP_REMOTE)))    /*lint !e502 */
  327.         fsm_p->state = fsmOPENED;
  328.  
  329.     ppp_p->flags &= ~flag;        /*lint !e502 */
  330.     ppp_ready (ppp_p);
  331. }
  332.  
  333.  
  334.  
  335. /****************************************************************************/
  336. /* Check request from remote host */
  337. static int
  338. pap_request (struct fsm_s *fsm_p, struct config_hdr *hdr, struct mbuf *data)
  339. {
  340. struct mbuf *reply_bp, **datap = &data;
  341. int result;
  342. char const *message;
  343. int mess_length;
  344. char *username = NULLCHAR;
  345. int userlen;
  346. char *password = NULLCHAR;
  347. int passwordlen;
  348.  
  349.     PPP_DEBUG_ROUTINES ("pap_request()");
  350.  
  351.     /* Extract userID/password sent by remote host */
  352.     if ((userlen = pullchar (&data)) != -1) {
  353.         register int i;
  354.         register char *cp;
  355.  
  356.         cp = username = mallocw ((unsigned) userlen + 1);
  357.         for (i = userlen; i-- > 0; )
  358.             *cp++ = (char) PULLCHAR (datap);
  359.  
  360.         *cp = '\0';
  361.     }
  362. #ifdef PPP_DEBUG_OPTIONS
  363.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  364.         trace_log (PPPiface, "    checking user: %s", username);
  365. #endif
  366.  
  367.     if ((passwordlen = pullchar (&data)) != -1) {
  368.         register int i;
  369.         register char *cp;
  370.  
  371.         cp = password = mallocw ((unsigned) passwordlen + 1);
  372.         for (i = passwordlen; i-- > 0; )
  373.             *cp++ = (char) PULLCHAR (datap);
  374.  
  375.         *cp = '\0';
  376.     }
  377. #ifdef PPP_DEBUG_OPTIONS
  378.     if (PPPtrace & PPP_DEBUG_OPTIONS)
  379.         trace_log (PPPiface, "    checking password: %s", password);
  380. #endif
  381.  
  382.     if (pap_verify (username, password) == 0) {
  383.         free (fsm_p->ppp_p->peername);
  384.         fsm_p->ppp_p->peername = strdup (username);
  385.         result = CONFIG_ACK;
  386.         message = " Welcome";
  387.     } else {
  388.         result = CONFIG_NAK;
  389.         message = " Invalid username or password";
  390.     }
  391.  
  392.     /* the space at the beginning of the message is crucial */
  393.     /* it is replaced with the length of the message */
  394.     mess_length = (int) strlen (message);
  395.     reply_bp = qdata ((unsigned const char *) message, (int16) mess_length);
  396.     reply_bp->data[0] = uchar(mess_length - 1);
  397.  
  398.     (void) fsm_send (fsm_p, uchar(result), hdr->id, reply_bp);
  399.  
  400.     if (result == CONFIG_NAK) {
  401.         if (fsm_p->retry_nak > 0)
  402.             fsm_p->retry_nak--;
  403.         else
  404.             pap_shutdown (fsm_p);
  405.     }
  406.     free_p (data);
  407.     free (username);
  408.     free (password);
  409.     return (result != CONFIG_ACK);
  410. }
  411.  
  412.  
  413.  
  414. /* Check acknowledgement from remote host */
  415. static int
  416. pap_check (struct fsm_s *fsm_p, struct config_hdr *hdr, struct mbuf *data)
  417. {
  418. struct pap_s *pap_p = fsm_p->pdv;
  419. char *message;
  420. int mess_length;
  421. int full_length;
  422. int len;
  423.  
  424.     PPP_DEBUG_ROUTINES ("pap_check()");
  425.  
  426.     /* ID field must match last request we sent */
  427.     if (hdr->id != fsm_p->lastid) {
  428.         PPP_DEBUG_CHECKS ("PAP: wrong ID");
  429.         tprintf ("id mismatch hdrid=%d, lastid=%d\n", hdr->id, fsm_p->lastid);
  430.         free_p (data);
  431.         return -1;
  432.     }
  433.     /* Log ASCII message from remote host, if any */
  434.     if ((mess_length = pullchar (&data)) != -1) {
  435.         message = mallocw ((unsigned) mess_length + 1);
  436.         full_length = len_p (data);
  437.         len = dqdata (data, (unsigned char *) message, (unsigned) mess_length);
  438.         message[len] = '\0';
  439.  
  440.         free (pap_p->message);
  441.         pap_p->message = message;
  442.  
  443.         if (PPPtrace) {
  444.             trace_log (PPPiface, "%s PPP/PAP %s %s: %s",
  445.                 fsm_p->ppp_p->iface->name,
  446.                 (len < mess_length) ? "Short"
  447.                 : (mess_length < full_length) ? "Long" : "Valid",
  448.                 (hdr->code == CONFIG_ACK) ? "Ack" : "Nak", message);
  449.         }
  450.         return (len < mess_length || mess_length < full_length);
  451.     }
  452.     free_p (data);
  453.     PPP_DEBUG_CHECKS ("PAP: missing message count");
  454.     return -1;
  455. }
  456.  
  457.  
  458.  
  459. /************************************************************************/
  460. /*            E V E N T   P R O C E S S I N G            */
  461. /************************************************************************/
  462.  
  463. /* Process incoming packet */
  464. void
  465. pap_proc (struct fsm_s *fsm_p, struct mbuf *bp)
  466. {
  467. struct pap_s *pap_p = fsm_p->pdv;
  468. struct config_hdr hdr;
  469.  
  470.     PPPtrace = fsm_p->ppp_p->trace;
  471.     PPPiface = fsm_p->ppp_p->iface;
  472.  
  473.     if (ntohcnf (&hdr, &bp) == -1)
  474.         fsm_log (fsm_p, "short authentication packet");
  475.  
  476.     if (PPPtrace > 1)
  477.         trace_log (PPPiface, "%s PPP/%s Recv,  option: %s, id: %d, len: %d",
  478.             fsm_p->ppp_p->iface->name, fsm_p->pdc->name,
  479.             fsmCodes[hdr.code], hdr.id, hdr.len);
  480.  
  481.     hdr.len -= CONFIG_HDR_LEN;    /* Length includes envelope */
  482.     trim_mbuf (&bp, hdr.len);    /* Trim off padding */
  483.  
  484.     switch (hdr.code) {
  485.         case CONFIG_REQ:
  486.             if (pap_request (fsm_p, &hdr, bp) == 0)
  487.                 pap_opening (fsm_p, PPP_AP_LOCAL);
  488.             break;
  489.  
  490.         case CONFIG_ACK:
  491.             if (pap_check (fsm_p, &hdr, bp) == 0) {
  492.                 alert (pap_p->pp, -1);
  493.                 pap_opening (fsm_p, PPP_AP_REMOTE);
  494.             }
  495.             break;
  496.  
  497.         case CONFIG_NAK:
  498.             if (pap_check (fsm_p, &hdr, bp) == 0) {
  499.                 stop_timer (&(fsm_p->timer));
  500.  
  501.                 /* Must have sent a bad username or password */
  502.                 free (pap_p->username);
  503.                 pap_p->username = NULLCHAR;
  504.                 free (pap_p->password);
  505.                 pap_p->password = NULLCHAR;
  506.  
  507.                 ksignal (pap_p, 1);
  508.             }
  509.             break;
  510.  
  511.         default:
  512.             if (PPPtrace)
  513.                 trace_log (PPPiface, "%s PPP/Pap Unknown packet type: %d;"
  514.                        " dropping packet", fsm_p->ppp_p->iface->name, hdr.code);
  515.             free_p (bp);
  516.             break;
  517.     }
  518. }
  519.  
  520.  
  521.  
  522. /* Timeout while waiting for reply from remote host */
  523. static void
  524. pap_timeout (void *vp)
  525. {
  526. struct fsm_s *fsm_p = (struct fsm_s *) vp;
  527. struct pap_s *pap_p = fsm_p->pdv;
  528.  
  529.     PPPtrace = fsm_p->ppp_p->trace;
  530.     PPPiface = fsm_p->ppp_p->iface;
  531.  
  532.     fsm_log (fsm_p, "Timeout");
  533.  
  534.     if (fsm_p->retry > 0) {
  535.         free (pap_p->message);
  536.         pap_p->message = strdup ("Request timeout");
  537.         ksignal (pap_p, 1);
  538.     } else {
  539.         free (pap_p->message);
  540.         pap_p->message = strdup ("Request retry exceeded");
  541.         ksignal (pap_p, 1);
  542.         kwait (NULL);
  543.         fsm_log (fsm_p, "Request retry exceeded");
  544.         pap_shutdown (fsm_p);
  545.     }
  546. }
  547.  
  548.  
  549.  
  550. /************************************************************************/
  551. /*            I N I T I A L I Z A T I O N            */
  552. /************************************************************************/
  553.  
  554. void
  555. pap_down (struct fsm_s *fsm_p)
  556. {
  557. struct pap_s *pap_p = fsm_p->pdv;
  558.  
  559.     if (pap_p == NULL)
  560.         return;
  561.  
  562.     PPPtrace = fsm_p->ppp_p->trace;
  563.     PPPiface = fsm_p->ppp_p->iface;
  564.  
  565.     fsm_log (fsm_p, "Down");
  566.  
  567.     fsm_p->flags = FALSE;
  568.  
  569.     switch (fsm_p->state) {
  570.         case fsmREQ_Sent:
  571.             stop_timer (&(fsm_p->timer));
  572.             alert (pap_p->pp, EABORT);
  573.             /* fallthru */
  574.         case fsmOPENED:
  575.         case fsmLISTEN:
  576.         case fsmTERM_Sent:
  577.             fsm_p->state = fsmCLOSED;
  578.             break;
  579.  
  580.         case fsmCLOSED:
  581.             /* Already closed; nothing to do */
  582.             break;
  583.         default:
  584.             break;
  585.     }
  586. }
  587.  
  588.  
  589.  
  590. static void
  591. pap_free (struct fsm_s *fsm_p)
  592. {
  593. struct pap_s *pap_p = fsm_p->pdv;
  594.  
  595.     free (pap_p->username);
  596.     free (pap_p->password);
  597.     free (pap_p->message);
  598. }
  599.  
  600.  
  601.  
  602. /* Initialize configuration structure */
  603. void
  604. pap_init (struct ppp_s *ppp_p)
  605. {
  606. struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  607. struct timer *t;
  608.  
  609.     PPPtrace = ppp_p->trace;
  610.     PPPiface = ppp_p->iface;
  611.  
  612.     PPP_DEBUG_ROUTINES ("pap_init()");
  613.  
  614.     if (fsm_p->pdv != NULL)
  615.         return;        /* already initialized */
  616.  
  617.     fsm_p->ppp_p = ppp_p;
  618.     fsm_p->pdc = &pap_constants;
  619.     fsm_p->pdv = callocw (1, sizeof (struct pap_s));
  620.  
  621.     fsm_p->try_req = fsm_p->pdc->try_req;
  622.     fsm_p->try_nak = fsm_p->pdc->try_nak;
  623.     fsm_p->try_terminate = fsm_p->pdc->try_terminate;
  624.  
  625.     fsm_p->state = fsmCLOSED;
  626.     fsm_p->retry = fsm_p->try_req;
  627.     fsm_p->retry_nak = fsm_p->try_nak;
  628.  
  629.     /* Initialize timer */
  630.     t = &(fsm_p->timer);
  631.     t->func = (void (*)(void *)) pap_timeout;
  632.     t->arg = (void *) fsm_p;
  633.     set_timer (t, fsm_p->pdc->timeout);
  634.     fsm_timer (fsm_p);
  635.     stop_timer (t);
  636. }
  637.  
  638.  
  639.  
  640. /* Initialize state machine for local */
  641. int
  642. pap_local (struct ppp_s *ppp_p)
  643. {
  644. struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  645.  
  646.     PPPtrace = ppp_p->trace;
  647.  
  648.     PPP_DEBUG_ROUTINES ("pap_local()");
  649.  
  650.     fsm_p->state = fsmLISTEN;
  651.     fsm_p->flags |= PPP_AP_LOCAL;
  652.     ppp_p->flags |= PPP_AP_LOCAL;
  653.     fsm_p->retry = fsm_p->try_req;
  654.     return 0;
  655. }
  656.  
  657.  
  658.  
  659. /* Initialize state machine for remote */
  660. int
  661. pap_remote (struct ppp_s *ppp_p)
  662. {
  663. struct fsm_s *fsm_p = &(ppp_p->fsm[Pap]);
  664. struct pap_s *pap_p = fsm_p->pdv;
  665. char *ifn;
  666.  
  667.     PPPtrace = ppp_p->trace;
  668.  
  669.     PPP_DEBUG_ROUTINES ("pap_remote()");
  670.  
  671.     fsm_p->state = fsmREQ_Sent;
  672.     fsm_p->flags |= PPP_AP_REMOTE;
  673.     ppp_p->flags |= PPP_AP_REMOTE;
  674.  
  675.     /* build a process/session to monitor user/password progress */
  676.     ifn = if_name (ppp_p->iface, " PAP");
  677.     pap_p->pp = newproc (ifn, 512, pap_monitor, 0, ppp_p->iface, fsm_p, 0);
  678.     free (ifn);
  679.     return 0;
  680. }
  681.  
  682. #endif /* PPP */
  683.